package ru.ifmo.network;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.*;
import java.util.logging.Logger;

/**
 * @author avhaliullin
 */
public class View extends JFrame {
    private final Logger log = Logger.getAnonymousLogger();
    private final HostsStorage storage;
    private Map<String, HostsStorage.HostInfo> hostsMap = new HashMap<String, HostsStorage.HostInfo>();
    private DefaultListModel hostsVector = new DefaultListModel();
    private final JList hostsList = new JList(hostsVector);
    private final JList filesList = new JList();

    public View(final HostsStorage storage) {
        this.storage = storage;
        hostsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        storage.setListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                SwingUtils.invokeLaterIfNotEDT(new Runnable() {
                    public void run() {
                        HostsStorage.HostInfo hostInfo = (HostsStorage.HostInfo) e.getSource();
                        String address = hostInfo.getAddress();

                        if (HostsStorage.ACTION_DISCONNECTED.equals(e.getActionCommand())) {
                            log.info("Disconnecting");
                            if (hostsMap.containsKey(address)) {
                                int index = hostsVector.indexOf(hostsMap.remove(address));
                                if (hostsList.getSelectedIndex() == index) {
                                    filesList.setModel(getModel(new ArrayList<Object>()));
                                }
                                hostsVector.remove(index);
                            }
                            return;
                        }
                        HostsStorage.HostInfo old = hostsMap.put(address, hostInfo);

                        if (HostsStorage.ACTION_ALIVE.equals(e.getActionCommand())) {
                            if (old == null) {
                                hostsVector.addElement(hostInfo);
                            }
                        }
                        if (HostsStorage.ACTION_FILE_LIST.equals(e.getActionCommand())) {
                            newFileList(hostInfo.getFiles());
                        }
                        if (HostsStorage.ACTION_HOST_NAME.equals(e.getActionCommand())) {
                            hostsVector.set(hostsVector.indexOf(old), hostInfo);
                        }
                    }
                });

            }
        });
        hostsList.addListSelectionListener(new ListSelectionListener() {
            public void valueChanged(ListSelectionEvent e) {
                int selected = hostsList.getSelectedIndex();
                if (selected >= 0) {
                    newFileList(((HostsStorage.HostInfo) hostsVector.get(selected)).getFiles());
                }
            }
        });

        final JSplitPane mainBox = new JSplitPane();

        final JScrollPane hostsPane = new JScrollPane(hostsList);
        hostsPane.createVerticalScrollBar();
        hostsPane.createHorizontalScrollBar();

        final JScrollPane filesPane = new JScrollPane(filesList);
        filesPane.createVerticalScrollBar();
        filesPane.createHorizontalScrollBar();

        final Box downloadsBox = Box.createVerticalBox();
        JScrollPane downloadsPane = new JScrollPane(downloadsBox);
        downloadsPane.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Downloads"),
                BorderFactory.createEmptyBorder(5, 5, 5, 5)));
        downloadsPane.createVerticalScrollBar();
        downloadsPane.createHorizontalScrollBar();

        filesList.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() > 1 && filesList.getSelectedIndex() >= 0) {
                    HostsStorage.HostInfo hostInfo = (HostsStorage.HostInfo) hostsList.getSelectedValue();
                    String selectedFile = (String) filesList.getSelectedValue();

                    JFileChooser fileChooser = new JFileChooser();
                    int res = fileChooser.showSaveDialog(View.this);
                    if (res == JFileChooser.APPROVE_OPTION) {
                        Downloader downloader = storage.getFile(hostInfo.getAddress(), selectedFile);
                        downloadsBox.add(new DownloadView(downloader));
                        downloader.download(fileChooser.getSelectedFile());
                    }
                }
            }
        });

        JSplitPane listsPane = new JSplitPane();
        listsPane.setDividerLocation(0.5);
        mainBox.setDividerLocation(0.5);

        listsPane.add(hostsPane, JSplitPane.LEFT);
        listsPane.add(filesPane, JSplitPane.RIGHT);
        mainBox.add(listsPane, JSplitPane.LEFT);
        mainBox.add(downloadsPane, JSplitPane.RIGHT);
        add(mainBox);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

    private void newFileList(List<String> files) {
        List<String> filesSortedList = new ArrayList<String>(files);
        Collections.sort(filesSortedList);
        filesList.setModel(getModel(filesSortedList));
    }

    private static DefaultListModel getModel(List<? extends Object> list) {
        DefaultListModel model = new DefaultListModel();
        for (Object o : list) {
            model.addElement(o);
        }
        return model;
    }
}
